#pragma once

#include <jsoncpp/json/json.h>
#include <string>
#include <iostream>

#include "log.hpp"

//"length"\r\n"{                  }"\r\n  有效载荷长度 + 有效载荷（\r\n不算做有效载荷长度）

const static std::string SEP = "\r\n";

void Encode(std::string &massage)
{
    int len = massage.size();
    std::string len_str = std::to_string(len);
    massage = len_str + SEP + massage;
    massage += SEP;
}

std::string DeCode(std::string &inbuffer)
{
    //std::cout << "package: " << package << std::endl;
    int pos = inbuffer.find(SEP);
    if (pos == std::string::npos)
        return "";

    //"length"\r\n
    std::string len = inbuffer.substr(0, pos);
    int length = std::stoi(len);

    //std::cout << "len = " << length << std::endl;

    pos = inbuffer.find(SEP, pos + SEP.size());
    if (pos == std::string::npos)
        return "";


    //"length"\r\n"{              }"\r\n
    std::string ret = inbuffer.substr(len.size() + SEP.size(), length);
    int tatal = length + len.size() + 2 * SEP.size(); // massage的总长度
    inbuffer.erase(0, tatal);       //"length"\r\n"{              }"\r\n"length"\r\n"{    -> "length"\r\n"{
    return ret;
}

class Request
{
public:
    Request(int x = 0, int y = 0, char option = '+')
        : _x(x), _y(y), _option(option)
    {
    }

    // 序列化
    bool Serialize(std::string *Serialize_str)
    {
        Json::Value root;
        root["x"] = _x;
        root["option"] = _option;
        root["y"] = _y;

        Json::FastWriter writer;
        *Serialize_str = writer.write(root);

        return true;
    }

    // 反序列化
    bool Deserialize(const std::string &massage)
    {
        Json::Value root;
        Json::Reader reader;
        reader.parse(massage, root);

        Request res;
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _option = (char)(root["option"].asInt());

        return true;
    }

    int getX() { return _x; }
    int getY() { return _y; }
    char getOption() { return _option; };

private:
    int _x;
    int _y;
    char _option;
};

class Response
{
public:
    Response(int result = 0, int code = 0)
        : _result(result), _code(code)
    {
    }

    // 序列化
    bool Serialize(std::string* serialize_str)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::FastWriter writer;
        *serialize_str = writer.write(root);

        return true;
    }

    // 反序列化
    bool Deserialize(std::string &massage)
    {
        Json::Value root;
        Json::Reader reader;
        reader.parse(massage, root);

        _result = root["result"].asInt();
        _code = root["code"].asInt();

        return true;
    }

    int getResult() {return _result;}
    int getCode()   {return _code;}

private:
    int _result;
    int _code; // 0 -> 正常 1 -> 除零 2 -> 无法识别option
};